package spectra.ee.web.kb.service;

import java.sql.SQLException;
import java.util.*;

import com.ibatis.sqlmap.client.SqlMapClient;

import spectra.base.log.Logger;
import spectra.base.sql.ibatis.SqlMapperWeb;
import spectra.ee.web.kb.model.*;
import spectra.base.util.*;
import org.apache.commons.collections.map.CaseInsensitiveMap;

/**
 * KbServiceBase 클래스.
 *
 * @author kmhan
 */
public class KbServiceBase
{

    /** Logger객체. */
    private static Logger logger = Logger.getLoggerInstance(KbServiceBase.class.getName());

    /** SqlMapClient 객체. */
    protected static SqlMapClient sqlMap = SqlMapperWeb.getSqlMapWebInstance();

    /**
    * <pre>
    * TOPN FAQ가져오는 메소드
    * FAQ_KB_TOPN_SYSTEM_TYPE 환경설정에 있는값을 가져와서 시스템정의(TYSYS), 사용자정의(TYUSR)에 따른 TOP-N FAQ를 가져온다.
    * iCount개수만큼 리스트를 가져온다.
    * </pre>
    *
    * @param strDomainId 도메인아이디.
    * @param iCount 가져올개수.
    * @param strTopNType TOPN타입.
    * @return List TopN Faq목록
    */
    public List selectTopnFaq(String strDomainId, int iCount, String strTopNType)
    {
        List list = null;
        try
        {
            Kb obj = new Kb();
            obj.setDomainId(strDomainId);
            obj.setEndNo(iCount);
            obj.setTopnType(strTopNType);
            obj.setCurrentDate(DateUtil.getCurrDateTimeStamp());
            list = (List) sqlMap.queryForList("Kb.selectTopnFaq", obj);
        }
        catch (SQLException e)
        {
            logger.error(e.getMessage());
        }
        return list;
    }

    /**
    * <pre>
    * 새로 등록된 FAQ를 가져오는 메소드
    * </pre>.
    *
    * @param strDomainId 도메인아이디.
    * @param iCount 가져올개수.
    * @return List 새로등록된 FAQ목록.
    */
    public List selectNewFaq(String strDomainId, int iCount)
    {
        List listRet = null;
        try
        {
            Kb obj = new Kb();
            obj.setDomainId(strDomainId);
            obj.setEndNo(iCount);
            obj.setCurrentDate(DateUtil.getCurrDateTimeStamp());
            listRet = (List) sqlMap.queryForList("Kb.selectNewFaq", obj);
        }
        catch (SQLException e)
        {
            logger.error(e.getMessage());
        }
        return listRet;
    }

    /**
    * <pre>
    * 해당 카테고리에 속하는 FAQ 리스트의 개수를 가져오는 메소드
    * </pre>.
    *
    * @param strNodeId 노드아이디.
    * @return 해당 카테고리에 속하는 FAQ 리스트의 개수.
    * @throws Exception the exception.
    */
    public int selectFaqListCount(String strNodeId) throws Exception
    {
        Kb obj = new Kb();
        obj.setNodeId(strNodeId);
        obj.setCurrentDate(DateUtil.getCurrDateTimeStamp());
        return ((Integer)sqlMap.queryForObject("Kb.selectFaqListCount", obj)).intValue();
    }

    /**
    * <pre>
    * 해당 카테고리에 속하는 FAQ 리스트를 가져오는 메소드
    * </pre>.
    *
    * @param iRowsPerPage 한 페이지마다 가져올 리스트 개수(환경설정값에서 읽어옴).
    * @param iPageNo 현재 페이지.
    * @param strNodeId 노드아이디.
    * @param strOrderBy 정렬 방법(환경설정값에서 읽어옴).
    * @return List 해당 카테고리에 속하는 FAQ 리스트.
    */
    public List selectFaqList(int iRowsPerPage, int iPageNo, String strNodeId, String strOrderBy)
    {
        List listRet = null;
        int iStartNum = iRowsPerPage * (iPageNo - 1) + 1;

        Kb obj = new Kb();
        obj.setRowsPerPage(iRowsPerPage);
        obj.setEndNo(iPageNo * iRowsPerPage);
        obj.setStartNo(iStartNum);
        obj.setNodeId(strNodeId);
        obj.setOrderBy(strOrderBy);
        obj.setCurrentDate(DateUtil.getCurrDateTimeStamp());
        try
        {
            listRet = (List)sqlMap.queryForList("Kb.selectFaqList", obj);
        }
        catch (SQLException e)
        {
            logger.error(e.getMessage());
        }
        return listRet;
    }

    /**
    * <pre>
    * 도메인에 속하는 카테고리를 트리 형식으로 가져오는 메소드
    * 도메인 노드 제외한 모든 FAQ 카테고리를 가져옴
    * </pre>.
    *
    * @param domainId 도메인아이디
    * @return List 도메인 노드 제외한 모든 FAQ 카테고리.
    */
    public List selectNodeTree(String domainId)
    {
        List listRet = null;
        try
        {
            listRet = (List)sqlMap.queryForList("Kb.selectNodeTree", domainId);
        }
        catch (SQLException e)
        {
            logger.error(e.getMessage());
        }
        return listRet;
    }

    /**
    * <pre>
    * 해당 노드의 FAQ 자식 노드를 가져오는 메소드
    * </pre>.
    *
    * @param nodeId 노드아이디
    * @return List 해당 노드의 FAQ 자식 노드를 가져오는 메소드.
    */
    public List selectNode(String nodeId)
    {
        List listRet = null;
        try
        {
            listRet = (List)sqlMap.queryForList("Kb.selectNode", nodeId);
        }
        catch (SQLException e)
        {
            logger.error(e.getMessage());
        }
        return listRet;
    }

    /**
    * <pre>
    * TOP키워드를 가져오는 메소드이다.
    * strTopKeywordType TYSYS - 시스템, TYUSR - 사용자정의
    * </pre>
    *
    * @param strDomainId 도메인아이디
    * @param strTopKeywordType 키워드타입(TYSYS, TYUSR)
    * @param iTopKeywordCount 키워드개수
    * @return List TOP키워드 리스트.
    */
    public List selectTopKeyword(String strDomainId, String strTopKeywordType, int iTopKeywordCount)
    {
        List list = null;
        try
        {
            TopKeyword topKeyword = new TopKeyword();
            topKeyword.setDomainId(strDomainId);
            topKeyword.setServiceType("SVFAQ");
            topKeyword.setSystemType(strTopKeywordType);
            topKeyword.setEndNo(iTopKeywordCount);

            list = (List) sqlMap.queryForList("TopKeyword.selectTopKeywordListByDomainId", topKeyword);
        }
        catch (SQLException e)
        {
            logger.error(e.getMessage());
        }
        return list;
    }

    /**
    * 지식ID로 내용가져오는 메소드.
    *
    * @param strKbId 지식ID.
    * @return strContents FAQ내용.
    */
    public String selectKbContents(String strKbId)
    {
        String strContents = "";
        List list = null;
        try
        {
            list = (List)sqlMap.queryForList("Kb.selectKbContentsByKbId", strKbId);
            if (list != null && list.size() > 0)
            {
                CaseInsensitiveMap map = null;

                for (int i = 0; i < list.size(); i++)
                {
                    map = (CaseInsensitiveMap)list.get(i);
                    strContents += map.get("CONTENTS");
                }
            }
        }
        catch (SQLException e)
        {
            logger.error(e.getMessage());
        }
        return strContents;
    }

    /**
    * 노드ID로 부모 노드 가져오는 메소드.
    *
    * @param nodeId 노드ID.
    * @return parentNode 부모노드ID
    * @throws Exception the exception
    */
    public String selectParentNode(String nodeId) throws Exception
    {
        String parentNode = null;
        try
        {
            parentNode = (String) sqlMap.queryForObject("Kb.selectParentNode", nodeId);
        }
        catch (SQLException e)
        {
            logger.error(e.getMessage());
        }

        return parentNode;
    }

    /**
    * 노드ID로 노드명 가져오는 메소드.
    *
    * @param nodeId 노드ID.
    * @return nodeName 노드명.
    * @throws Exception the exception
    */
    public String selectNodeName(String nodeId) throws Exception
    {
        String nodeName = null;
        try
        {
            nodeName = (String) sqlMap.queryForObject("Kb.selectNodeName", nodeId);
        }
        catch (SQLException e)
        {
            logger.error(e.getMessage());
        }

        return nodeName;
    }

    /**
    * 지식ID로 FAQ의 상세 내용 가져오는 메소드.
    * @param kbId 지식ID.
    * @return List 지식ID로 가져온 내용 리스트. 
    */
    public List selectContentsByKbId(String kbId)
    {
        List list = null;
        try
        {
            list = (List) sqlMap.queryForList("Kb.selectContentsByKbId", kbId);
        }
        catch (SQLException e)
        {
            logger.error(e.getMessage());
        }
        return list;
    }

    /**
    * 지식ID로 FAQ의 이전글, 다음글 가져오는 메소드.
    *
    * @param strNodeId 노드아이디
    * @param strOrderBy 정렬 방법(환경설정값에서 읽어옴)
    * @param strKbId 지식ID.
    * @return List FAQ이전/다음 리스트. 
    */
    public List selectKbPrevNext(String strKbId, String strNodeId, String strOrderBy)
    {
        List listRet = null;

        Kb obj = new Kb();
        obj.setKbId(strKbId);
        obj.setNodeId(strNodeId);
        obj.setOrderBy(strOrderBy);
        obj.setCurrentDate(DateUtil.getCurrDateTimeStamp());
        try
        {
            listRet = (List)sqlMap.queryForList("Kb.selectKbPrevNext", obj);
        }
        catch (SQLException e)
        {
            logger.error(e.getMessage());
        }
        return listRet;
    }

    /**
    * 지식ID로 FAQ의 조회수를 증가시키는 메소드.
    *
    * @param kbId 지식ID.
    * @return boolean 성공시 true, 실패시 false
    */
    public boolean updateKbHitCount(String kbId)
    {
        boolean result = false;
        int iResult = -1;
        Kb obj = new Kb();
        obj.setKbId(kbId);
        try
        {
            sqlMap.startTransaction();
            iResult = sqlMap.update("Kb.updateKbHitCount", kbId);
            sqlMap.commitTransaction();
            if(iResult > 0)
            {
                result = true;
            }
        }
        catch (SQLException e)
        {
            logger.error(e.getMessage());
        }
        finally
        {
            try
            {
                sqlMap.endTransaction();
            }
            catch(SQLException e)
            {
                logger.error(e.getMessage());
            }
        }
        return result;
    }

    /**
    * 지식ID로 FAQ의 조회 Log를 만드는 메소드.
    *
    * @param logId 로그ID.
    * @param kbId 지식ID.
    * @param serviceType 서비스타입.
    * @param nodeId 노드ID.
    * @return boolean 성공시 true, 실패시 false
    */
    public boolean insertKbViewLog(String logId, String kbId, String serviceType, String nodeId)
    {
        boolean result = false;
        int iResult = -1;

        Kb obj = new Kb();
        obj.setServiceType(serviceType);
        obj.setKbId(kbId);
        obj.setLogId(logId);
        obj.setNodeId(nodeId);
        obj.setCurrentDate(DateUtil.getCurrDateTimeStamp());

        try
        {
            sqlMap.startTransaction();
            iResult = sqlMap.update("Kb.insertKbViewLog", obj);
            sqlMap.commitTransaction();
            if(iResult > 0)
            {
                result = true;
            }
        }
        catch (SQLException e)
        {
            logger.error(e.getMessage());
        }
        finally
        {
            try
            {
                sqlMap.endTransaction();
            }
            catch(SQLException e)
            {
                logger.error(e.getMessage());
            }
        }
        return result;
    }
}
